保姆级神器,再也不用担心搞崩了!
吕昱峰 | https://zhuanlan.zhihu.com/p/422462131
大家好,我是 Jack。
所谓工欲善其事,必先利其器。
做深度学习相关的任务,GPU 不可或缺,但是等到买了一堆卡,配置好了裸机之后,问题也就接踵而来了。
由于是经验总结,也不避讳什么,相信下面的情况各个组里的同学都有遇到过:
实验室多人混用一个物理机,来个小白装库分分钟给你把环境乃至系统搞崩了; 没有清晰的存储区域划分,/root或者/home/user_name 代码数据乱放,随时满; 多人使用一台物理机需要抢占; 实验室新人不敢让他碰环境,老人又不想当运维; 有的人爱在终端起任务,有的人爱开notebook写; 。。。。
今天,给大家带来一款神器,解决这些的痛点!
实验室GPU管理的需求
环境稳定!环境稳定!环境稳定!重要的事情说三遍!没有人希望公用的环境时不时的崩了,而且高校基本上不存在运维的人(名义上招进来实际在干啥相信同学们也知道)。 兼容性好,即可以满足各种版本的Nvidia-driver+CUDA+框架的组合。为什么?因为你要复现别人的代码啊,起码要跑一下吧,作者能给开源就不错了,不会给你持续更新,你只能装人家readme要求的版本。这时候物理机装着一大堆的环境,不断升级降级,换谁不崩溃。 升级+维护简单。理由也很简单,因为没有运维。 屏蔽物理机权限(开docker镜像),谁刚来都可能是小白,但谁也都不希望小白给自己瞎整,甚至给小白擦屁股。 任务式管理。如果遇上需要抢占显卡的情况,能够排队。相信一起共用物理机的同学都体会过kill和被kill进程的“快感”。
Determined——完美的解决方案
Determined是一家国外创业公司做的集群管理+可视化作业+模型调优一体的解决方案,当然这里我选择它的原因主要还是集群管理。从2019年开始我就在各处找合适的方案,期间也用过微软的OpenPAI,基本能够满足上述的1,2,4,5。但是难受就难受在环境依赖一大堆,科学上网只要不稳,升个级要费上好几天。手动改了一些shell脚本替换成国内源,但是更新了几个大版本要跟着改,实验室就我一个人会升级,就很难顶。
下面再说说为什么Determined是完美解决方案:
安装只需要一个Python包,pip install一下就OK了。包括升级也是一行搞定,省事。 操作系统随便apt update/upgrade, nvidia-driver随便升级最新版,不影响使用。 只有docker本身pull镜像依赖科学上网。 前面提到的所有GPU管理的需求都能满足。
说白了,安装简单,升级没限制,用起来舒适。
Determined安装
这里就事无巨细的把所有的安装步骤都写一下,当然官网文档其实写的已经很清楚了,先放个链接:
https://docs.determined.ai/latest/sysadmin-deploy-on-prem/index.html
下面开始进行安装步骤说明:
1. 安装全新的Ubuntu系统,建议选择18.04或20.04的长期维护版。
为什么选择Ubuntu?CentOS官方已经放弃了,另外apt直装nvidia-driver非常友好,非要用run包的请绕道。
2. 安装Docker
这里给出两个安装方式,首先是determined官方给的方式(注意此方式需要科学上网):
sudo apt-get update && sudo apt-get install -y software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update && sudo apt-get install -y --no-install-recommends docker-ce
sudo systemctl reload docker
sudo usermod -aG docker $USER
或者:
sudo apt install docker.io
3. 安装nvidia-container-toolkit
用于Docker容器内调用GPU(注意需要科学上网)
curl -fsSL https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y --no-install-recommends nvidia-container-toolkit
sudo systemctl restart docker
4. 配置docker代理,方便后续pull镜像能够顺利
创建配置文件目录和配置文件
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo touch /etc/systemd/system/docker.service.d/http-proxy.conf
添加HTTP_PROXY环境变量。其中[proxy-addr]和[proxy-port]分别改成实际情况的代理地址和端口:
[Service]
Environment="HTTP_PROXY=http://[proxy-addr]:[proxy-port]/"
Environment="HTTPS_PROXY=https://[proxy-addr]:[proxy-port]/"
更新配置并重启Docker
systemctl daemon-reload
systemctl restart docker
最后查看一下是否生效
docker info
输出中包含如图的HTTP PROXY和HTTPS PROXY即可。
5. 安装Determined
pip install determined
至此安装准备工作完成,下面进行集群配置。
Determined集群配置
先放一个Determined的AWS部署图,本地部署结构也是类似的:
可以看到Determined集群节点由一个Master和无数个Agent构成,其中Master作为Client访问入口,即通过网页、CLI等方式发起请求,通过Master发送到agents进行调度。此外还需要有独立的存储位置。
这里给出一套简单的集群配置:
Master节点1个,简单的server,不需要GPU 存储节点1个,具体空间自定,建议不小于4T(可与Master为同一节点) Agent节点若干,GPU服务器,建议将同型号卡分组 万兆交换机连接,保证网络存储速度。
首先将所有节点连接到同一局域网,并按照上面的安装教程安装给所有机器安装依赖环境(Master和存储节点不需要安装nvidia相关的内容)
然后启动Master节点:
det deploy local master-up
一般直接启动即可,web访问端口为8080,有具体配置需求可以参考详细配置文档。
然后配置GPU节点,这里需要将不同型号的卡进行分组,需要配置yaml文件:
## The hostname or IP address of the Determined master.
master_host: ip_of_your_master_node
## The port of the Determined master.
master_port: 8080
## The ID of this agent; defaults to the hostname of the current machine. Agent IDs must be unique
## within a cluster.
agent_id: rtx3090_0
## The label of this agent. Agents with labels may only run workloads with the
## corresponding label.
label: rtx3090
## The GPUs that should be exposed as slots by the agent. A comma-separated list of GPUs,
## each specified by a 0-based index, UUID, PCI bus ID, or board serial number.
http_proxy: ip_of_proxy
https_proxy: ip_of_proxy
这里主要配置3个内容:
Master节点,用于识别Master节点 agent_id和label,分别对应本机id和组名,根据显卡型号命名即可 科学上网代理
完成后,所有agent节点使用如下命令启动:
docker run --gpus all -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD"/agent-config.yaml:/etc/determined/agent.yaml determinedai/determined-agent:0.15.6
注意最后的版本号要和安装的determined版本号对应,一般为最新。
除此之外,还需要讲存储节点进行分布式存储的配置,一般可以采用NFS或者Ceph,这里给出NFS的配置教程和Ceph官方文档,可参考配置,具体步骤不再赘述:
https://docs.ceph.com/en/pacific/ https://ubuntu.com/server/docs/service-nfs
注意:所有Agent挂载存储到同一位置,如/mnt/data,才能保证任意任务都可以使用同一配置启动。
使用Determined
Determined主要有两种使用方式,Web和CLI。其中web可以直接通过Master节点IP:8080进行访问,具体界面如下:
可以直接通过网页端创建任务(不推荐)。
这里详细介绍CLI的用法,因为网页端创建任务无法自定义存储路径和加载的Docker镜像,灵活度十分受限。
在终端机安装determined,pip install determined即可 在环境变量配置MASTER节点IP
nano ~/.bashrc
# 添加如下内容:
# export DET_MASTER=ip_of_your_master_node
source ~/.bashrc
使用determined cli创建任务
首先需要登录:
det user login
# 输入账号密码即可
admin用户可以管理用户添加删除,具体参考用户管理文档。
然后写一个开启任务的yaml配置文件,这里给出一个参考:
description: your_task_name
resources:
agent_label: rtx3090
slots: 1
bind_mounts:
- host_path: /mnt/dl/lvyufeng/
container_path: /run/determined/workdir/lv/
environment:
image: determinedai/environments:cuda-11.1-pytorch-1.9-lightning-1.3-tf-2.4-gpu-0.16.3
environment_variables:
- http_proxy=your_proxy
- https_proxy=your_proxy
以上涵盖了开启任务所需的基本设置,包括:
description: 任务名 resources: 要开启任务的GPU类型(对应label)和数量(对应slots) bind_mounts: 挂载分布式存储到docker容器内,host_path为物理机路径(这是为什么我上面让所有agent设置同一个路径的原因),container_path为容器内路径,建议使用/run/determined/workdir/xxx, 因为notebook默认路径为/run/determined/workdir/这样进入即可使用。 environment: docker容器的环境配置,包括使用的镜像和环境变量。
完成后,可以选择开启notebook或者cmd终端,这取决于使用者的习惯。
# notebook
det notebook start --config-file config.yaml
# shell
det shell start --config-file config.yaml
这里还有一个比较实用的用法,VSCode配合Shell进行远程调试,可以参考官网文档使用:
https://docs.determined.ai/latest/features/commands-and-shells.html#visual-studio-code
自定义Docker镜像
安装和使用都OK之后,部分同学会有自定义Docker镜像的需求,即修改:
environment:
image: determinedai/environments:cuda-11.1-pytorch-1.9-lightning-1.3-tf-2.4-gpu-0.16.3
自定义Docker镜像可以把自己需要的环境打包,如我个人需要的ROUGE包或者MindSpore环境,均可以通过自定义镜像完成,后续直接pull自己的镜像即可。
由于Determined官方其实给出了很多个版本的cuda和框架的组合,这里先给出链接供大家直接使用:
https://hub.docker.com/r/determinedai/environments/tags
大多数常用的环境都已经打包好,这里就不多说了。下面说一下自定义镜像的方法:
1. 克隆官方environments仓库
git clone https://github.com/determined-ai/environments
2. 添加想要安装的环境相关命令
cd det_dockerfile_scripts
touch your_script.sh
# add install instructions to your_script.sh
3. 修改Dockerfile
nano Dockerfile-base-gpu
# add `RUN /tmp/det_dockerfile_scripts/your_script.sh`
4. 参考Makefile里的命令打包Docker镜像,然后上传到dockerhub
这里不给出Docker镜像打包的教程,如有需求可以自行搜索,determined官方已经给出了非常完整的打包脚本,根据readme修改和运行即可。
结语
实验室用个GPU不容易,总之用Determined属于一劳永逸,后续再来新人随便在Docker容器里造,也没多大关系,如果你们还在苦哈哈的一起用同一台物理机,时不时因为环境崩溃导致人也崩溃了。
另外,环境搞不好从来不是research做不下去的理由,现在的调参侠们可能真的连装环境这种基础技能都没有,也能吃大组红利刷顶会,何其哀哉!大概就这样吧。